package frame.options.simulation.create.virtualNetworks;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.SystemColor;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionListener;





import model.components.networks.network.VirtualNetwork;

@SuppressWarnings("serial")
public class VirtualNetworksPanel extends JPanel
{
	public static final String AVAILABLE_LIST = "AvailableList";
	
	public static final String ADD_BUTTON = "Add";
	public static final String ADD_ALL_BUTTON = "AddAll";
	
	public static final String REMOVE_BUTTON = "Remove";
	public static final String REMOVE_ALL_BUTTON = "RemoveAll";
	
	public static final String SELECTED_LIST = "SelectedList";
		
	private JList< VirtualNetwork > availableVirtualNetworksList;
	public JList< VirtualNetwork > getAvailableVirtualNetworksList(){ return availableVirtualNetworksList; }
	public void setAvailableVirtualNetworksList( JList< VirtualNetwork > availableVirtualNetworksList ){ this.availableVirtualNetworksList = availableVirtualNetworksList; }
	
	private DefaultListModel< VirtualNetwork > availableVirtualNetworksListModel;
	public DefaultListModel< VirtualNetwork > getAvailableVirtualNetworksListModel(){ return this.availableVirtualNetworksListModel; }
	public void setAvailableVirtualNetworksListModel( DefaultListModel< VirtualNetwork > availableVirtualNetworksListModel ){ this.availableVirtualNetworksListModel = availableVirtualNetworksListModel; }
	
    private JButton addButton;
    public JButton getAddButton(){ return this.addButton; }
    public void setAddButton( JButton addButton ){ this.addButton = addButton; }
    
    private JButton addAllButton;
    public JButton getAddAllButton(){ return this.addAllButton; }
    public void setAddAllButton( JButton addAllButton ){ this.addAllButton = addAllButton; }
    
    private JButton removeButton;
    public JButton getRemoveButton(){ return this.removeButton; }
    public void setRemoveButton( JButton removeButton ){ this.removeButton = removeButton; }
    
    private JButton removeAllButton;
    public JButton getRemoveAllButton(){ return this.removeAllButton; }
    public void setRemoveAllButton( JButton removeAllButton ){ this.removeAllButton = removeAllButton; }
    
	private JList< VirtualNetwork > selectedVirtualNetworksList;
	public JList< VirtualNetwork > getSelectedVirtualNetworksList(){ return selectedVirtualNetworksList; }
	public void setSelectedVirtualNetworksList( JList< VirtualNetwork > selectedVirtualNetworksList ){ this.selectedVirtualNetworksList = selectedVirtualNetworksList; }
	
	private DefaultListModel< VirtualNetwork > selectedVirtualNetworksListModel;
	public DefaultListModel< VirtualNetwork > getSelectedVirtualNetworksListModel(){ return selectedVirtualNetworksListModel; }
	public void setSelectedVirtualNetworksListModel( DefaultListModel< VirtualNetwork > selectedVirtualNetworksListModel ){ this.selectedVirtualNetworksListModel = selectedVirtualNetworksListModel; }
	    
    public VirtualNetworksPanel( List< VirtualNetwork > virtualNetworks )
    {
		this.setAvailableVirtualNetworksListModel( new DefaultListModel< VirtualNetwork >() );
		
		for( VirtualNetwork virtualNetwork: virtualNetworks )
			this.getAvailableVirtualNetworksListModel().addElement( virtualNetwork );
		
		this.setAvailableVirtualNetworksList( new JList< VirtualNetwork >( this.getAvailableVirtualNetworksListModel() ) );
		this.getAvailableVirtualNetworksList().setName( VirtualNetworksPanel.AVAILABLE_LIST );
		this.getAvailableVirtualNetworksList().setCellRenderer( new VirtualNetworksListCellRenderer() );
		
		this.setAddButton( new JButton( "Add >>" ) );
		this.getAddButton().setName( VirtualNetworksPanel.ADD_BUTTON );
		this.getAddButton().setEnabled( false );
		
		this.setAddAllButton( new JButton( "Add All >>" ) );
		this.getAddAllButton().setName( VirtualNetworksPanel.ADD_ALL_BUTTON );
		this.getAddAllButton().setEnabled( true );
		
		this.setRemoveButton( new JButton( "<< Remove" ) );
		this.getRemoveButton().setName( VirtualNetworksPanel.REMOVE_BUTTON );
		this.getRemoveButton().setEnabled( false );
		
		this.setRemoveAllButton( new JButton( "<< Remove All" ) );
		this.getRemoveAllButton().setName( VirtualNetworksPanel.REMOVE_ALL_BUTTON );
		this.getRemoveAllButton().setEnabled( false );
		
        this.setSelectedVirtualNetworksListModel( new DefaultListModel< VirtualNetwork >() );
        this.setSelectedVirtualNetworksList( new JList< VirtualNetwork >( this.getSelectedVirtualNetworksListModel() ) );
        this.getSelectedVirtualNetworksList().setName( VirtualNetworksPanel.SELECTED_LIST );
        this.getSelectedVirtualNetworksList().setCellRenderer( new VirtualNetworksListCellRenderer() );
    	
		this.setLayout( new java.awt.BorderLayout() );
        this.add( this.titlePanel(), BorderLayout.NORTH );
        this.add( this.contentPanel(), BorderLayout.CENTER );
    }
    
	private JPanel titlePanel()
	{
        JLabel titleLabel = new JLabel( "Virtual networks" );
        titleLabel.setFont( new Font( "MS Sans Serif", Font.BOLD, 14 ) );
        titleLabel.setBorder( new EmptyBorder( new Insets( 10, 10, 10, 10 ) ) );
        titleLabel.setOpaque( true );
        
        JSeparator separator = new JSeparator();
        
        JPanel titlePanel = new JPanel();
        titlePanel.setLayout( new java.awt.BorderLayout() );
        titlePanel.setBackground( Color.gray );
        titlePanel.add( titleLabel, BorderLayout.CENTER );
        titlePanel.add( separator, BorderLayout.SOUTH );
        
        return titlePanel;
	}
	
	private JPanel contentPanel()
	{
    	JPanel contentPanel = new JPanel();
    	contentPanel.setBorder( new EmptyBorder( new Insets( 50, 50, 50, 50 ) ) );
        contentPanel.add( this.availablePanel() );
        contentPanel.add( this.buttonsPanel() );
        contentPanel.add( this.selectedPanel() );
        
        return contentPanel;
	}
	
	private JPanel availablePanel()
	{
    	JLabel availableLabel = new JLabel( "Available" );
        availableLabel.setFont( new Font( "MS Sans Serif", Font.BOLD, 12 ) );
        availableLabel.setAlignmentX( JPanel.CENTER_ALIGNMENT );
        
		JScrollPane availableScrollPane = new JScrollPane( this.getAvailableVirtualNetworksList() );
		availableScrollPane.setPreferredSize( new Dimension( 200, 250 ) );
		availableScrollPane.setBorder( BorderFactory.createLineBorder( SystemColor.activeCaption, 2 ) );
				
		JPanel availablePanel = new JPanel();
        availablePanel.setLayout( new BoxLayout( availablePanel, BoxLayout.PAGE_AXIS ) );
        availablePanel.add( availableLabel );
        availablePanel.add( Box.createRigidArea( new Dimension( 0, 5 ) ) );
		availablePanel.add( availableScrollPane );
		
		return availablePanel;
	}
	
	private JPanel buttonsPanel()
	{
		JPanel buttonsPanel = new JPanel();
		buttonsPanel.setLayout( new GridLayout( 0, 1 ) );
		buttonsPanel.add( this.getAddButton() );
		buttonsPanel.add( this.getAddAllButton() );		
		buttonsPanel.add( new JLabel() );
		buttonsPanel.add( this.getRemoveButton() );
		buttonsPanel.add( this.getRemoveAllButton() );
		
		return buttonsPanel;
	}
	
	private JPanel selectedPanel()
	{
		JLabel selectedlabel = new JLabel( "Selected" );
		selectedlabel.setFont( new Font( "MS Sans Serif", Font.BOLD, 12 ) );
		selectedlabel.setAlignmentX( CENTER_ALIGNMENT );
		
        JScrollPane selectedScrollPanel = new JScrollPane( this.getSelectedVirtualNetworksList() );
		selectedScrollPanel.setPreferredSize( new Dimension( 200, 250 ) );
		selectedScrollPanel.setBorder( BorderFactory.createLineBorder( SystemColor.activeCaption, 2 ) );
		
		JPanel selectedPanel = new JPanel();
		selectedPanel.setLayout( new BoxLayout( selectedPanel, BoxLayout.Y_AXIS ) );
		selectedPanel.add( selectedlabel );
        selectedPanel.add( Box.createRigidArea( new Dimension( 0, 5 ) ) );
		selectedPanel.add( selectedScrollPanel );
		
		return selectedPanel;
	}
	
	public void addListeners( ActionListener actionListener, MouseListener mouseListener, ListSelectionListener listSelectionListener )
	{
		this.getAvailableVirtualNetworksList().addMouseListener( mouseListener );
		this.getAvailableVirtualNetworksList().addListSelectionListener( listSelectionListener );
		
		this.getAddButton().addActionListener( actionListener );
		this.getAddAllButton().addActionListener( actionListener );
		
		this.getRemoveButton().addActionListener( actionListener );
		this.getRemoveAllButton().addActionListener( actionListener );
		
		this.getSelectedVirtualNetworksList().addMouseListener( mouseListener );
		this.getSelectedVirtualNetworksList().addListSelectionListener( listSelectionListener );
    }

	public List< VirtualNetwork > getSelectedVirtualNetworks()
	{
		List< VirtualNetwork > virtualNetworks = new ArrayList< VirtualNetwork >();
		
		for( int i = 0; i < this.getSelectedVirtualNetworksListModel().size(); i++ )
			virtualNetworks.add( this.getSelectedVirtualNetworksListModel().get( i ) );
		
		return virtualNetworks;
	}
	
	public void mouseDoubleClicked( JList< VirtualNetwork > virtualNetworksList, int virtualNetworksListIndex )
	{
		VirtualNetwork virtualNetwork = virtualNetworksList.getModel().getElementAt( virtualNetworksListIndex );
		
		if( virtualNetworksList.getName().equals( VirtualNetworksPanel.AVAILABLE_LIST ) )
		{
			this.getSelectedVirtualNetworksListModel().addElement( virtualNetwork );
			this.getAvailableVirtualNetworksListModel().removeElementAt( virtualNetworksListIndex );
		}
		else
		{
			this.getAvailableVirtualNetworksListModel().addElement( virtualNetwork );
			this.getSelectedVirtualNetworksListModel().removeElementAt( virtualNetworksListIndex );
		}
	}
	public void performButtonAction( JButton button )
	{
		if( button.getName().equals( VirtualNetworksPanel.ADD_BUTTON ) )
		{
			for( VirtualNetwork virtualNetwork: this.getAvailableVirtualNetworksList().getSelectedValuesList() )
			{
				this.getSelectedVirtualNetworksListModel().addElement( virtualNetwork );
				this.getAvailableVirtualNetworksListModel().removeElement( virtualNetwork );
			}
		}
		else if( button.getName().equals( VirtualNetworksPanel.ADD_ALL_BUTTON ) )
		{
			for( int i = 0; i < this.getAvailableVirtualNetworksListModel().getSize(); i++ )
				this.getSelectedVirtualNetworksListModel().addElement( this.getAvailableVirtualNetworksListModel().getElementAt( i ) );
			
			this.getAvailableVirtualNetworksListModel().removeAllElements();
		}
		else if( button.getName().equals( VirtualNetworksPanel.REMOVE_BUTTON ) )
		{
			for( VirtualNetwork virtualNetwork: this.getSelectedVirtualNetworksList().getSelectedValuesList() )
			{
				this.getAvailableVirtualNetworksListModel().addElement( virtualNetwork );
				this.getSelectedVirtualNetworksListModel().removeElement( virtualNetwork );
			}
		}
		else if( button.getName().equals( VirtualNetworksPanel.REMOVE_ALL_BUTTON ) )
		{
			for( int i = 0; i < this.getSelectedVirtualNetworksListModel().getSize(); i++ )
				this.getAvailableVirtualNetworksListModel().addElement( this.getSelectedVirtualNetworksListModel().getElementAt( i ) );
			
			this.getSelectedVirtualNetworksListModel().removeAllElements();
		}
	}
	
	public void updateButtons()
	{
		if( !this.getAvailableVirtualNetworksList().isSelectionEmpty() )
			this.getAddButton().setEnabled( true );
		else
			this.getAddButton().setEnabled( false );
		
		if( this.getAvailableVirtualNetworksListModel().getSize() > 0 )
			this.getAddAllButton().setEnabled( true );
		else
			this.getAddAllButton().setEnabled( false );
		
		if( !this.getSelectedVirtualNetworksList().isSelectionEmpty() )
			this.getRemoveButton().setEnabled( true );
		else
			this.getRemoveButton().setEnabled( false );
		
		if( this.getSelectedVirtualNetworksListModel().getSize() > 0 )
			this.getRemoveAllButton().setEnabled( true );
		else
			this.getRemoveAllButton().setEnabled( false );
	}
		
}
